package io.geekidea.boot.system.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.collect.Maps;
import com.hwtx.form.domain.def.meta.config.FormComponentConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.stream.Streams;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;


@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@ToString
public class DataPermissionConfig {
    private String name;
    private String remark;
    private String apiCode;
    private Integer controller;
    private String type;
    private String modelName;

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        DataPermissionConfig that = (DataPermissionConfig) o;
        return Objects.equals(name, that.name) && Objects.equals(apiCode, that.apiCode) &&
                Objects.equals(controller, that.controller) && Objects.equals(type, that.type) &&
                Objects.equals(modelName, that.modelName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, apiCode, controller, type, modelName);
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    public static class WDataPermissionConfig extends DataPermissionConfig {
        @JsonDeserialize(using = String2ListMapDeserializer.class)
        private List<?> output;
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    public static class RDataPermissionConfig extends DataPermissionConfig {
        private List<FormComponentConfig.ParamMapping> output;
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    public static class SeriableDataPermissionConfig extends DataPermissionConfig {
        private String output;
    }

    public static class String2ListMapDeserializer extends JsonDeserializer<List<Map<String, String>>> {

        @Override
        public List<Map<String, String>> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            String value = null;
            JsonNode node = p.getCodec().readTree(p);
            if (node.isArray() && !node.isEmpty()) {
                value = node.toString();
            } else if (node.isTextual() && StringUtils.isNotBlank(node.asText())) {
                value = node.asText();
            }
            if (StringUtils.isEmpty(value)) {
                return null;
            }
            return Streams.of(value.split(",")).map(item -> {
                Map<String, String> paramMapping = Maps.newHashMap();
                String[] outs = item.split(":");
                if (outs.length == 2) {
                    paramMapping.putIfAbsent(outs[0], outs[1]);
                } else if (outs.length == 1) {
                    paramMapping.putIfAbsent(outs[0], null);
                }
                return paramMapping;
            }).toList();
        }
    }
}
